Ingress 是用來管理叢集外部訪問叢集內部 service 的元件。提供外部使用者透過 domain(網址) 來存取內部資源,具有路由的功能,可設定路徑規則將請求轉發至指定的 services。
Ingress 除了提供應用程式負載平衡的功能外,也可以設定 SSL 連線,以及將多個網站或 domain 架在同一個 IP 上的功能(基於網域名稱的虛擬主機,name-based virtual hosting)。
因 k8s 沒有實作 Ingress,要另外下載第三方的 Ingress controller,常見的有 Nginx Ingress Controller(k8s 官方維護的)、Traefik Ingress Controller 與 Istio Ingress:Istio。
這邊使用 minikube 並安裝 Nginx Ingress Controller 為範例,如何在叢集中建立 Ingress。
minikube addons enable ingress
kubectl get pods -n ingress-nginx
NAME                                        READY   STATUS      RESTARTS   AGE
ingress-nginx-admission-create-rqsg4        0/1     Completed   0          3m25s
ingress-nginx-admission-patch-rwwkr         0/1     Completed   1          3m25s
ingress-nginx-controller-7799c6795f-2x69n   1/1     Running     0          3m25s
kubectl create deployment web --image=gcr.io/google-samples/hello-app:1.0
deployment.apps/web created
建立一個 service,類型為 NodePort、port 為 8080。
kubectl expose deployment web --port=8080 --type=NodePort
service/web exposed
查看 service。
kubectl get svc web
NAME   TYPE       CLUSTER-IP    EXTERNAL-IP   PORT(S)          AGE
web    NodePort   10.97.40.77   <none>        8080:31721/TCP   74s
測試看看是否可以使用 Minikube IP 位址和 NodePort 來存取這個 hello world 程式。
minikube service web --url
http://127.0.0.1:50068
❗  Because you are using a Docker driver on darwin, the terminal needs to be open to run it.
點開 url 可以成功看到 hello world 程式。

準備一個設定檔 hello-ingress.yaml。
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: hello-ingress
spec:
  rules:
  - host: hello-world.info
    http:
      paths:
      - path: /
        pathType: Prefix
        backend:
          service:
            name: web
            port:
              number: 8080
以下解說 spec:
rules:設定 Ingress 的路由規則host:將來自 hello-world.info 的請求轉發至以下指定的 service
path:host 的路徑配對,這邊指對應到 hello-world.info/ 所有路徑建立 Ingress。
kubectl apply -f hello-ingress.yaml
ingress.networking.k8s.io/hello-ingress created
查看剛才建立的 Ingress,可以看到 ADDRESS 為 192.168.49.2。
kubectl get ingress
NAME            CLASS   HOSTS              ADDRESS        PORTS   AGE
hello-ingress   nginx   hello-world.info   192.168.49.2   80      7m15s
設定一下 /etc/hosts 將 hello-world.info 對應至該 IP 位址,這邊修改會需要管理者權限。
sudo vim /etc/hosts
這邊若是按照官方文件加入 ingress IP 192.168.49.2 hello-world.info,會連不到 hello-world.info,後來在這邊 stack overflow 看到要加入 127.0.0.1 hello-world.info,再另外執行以下指令。
minikube tunnel
✅  Tunnel successfully started
📌  NOTE: Please do not close this terminal as this process must stay alive for the tunnel to be accessible ...
❗  The service/ingress hello-ingress requires privileged ports to be exposed: [80 443]
🔑  sudo permission will be asked for it.
🏃  Starting tunnel for service hello-ingress.
最後前往 http://hello-world.info。 看到以下畫面。

當請求沒有對應到 Ingress 上的規則時,則會將流量轉發至 Default backend。
kubectl describe ingress hello-ingress
Name:             hello-ingress
Labels:           <none>
Namespace:        default
Address:          192.168.49.2
Ingress Class:    nginx
Default backend:  <default>
Rules:
  Host              Path  Backends
  ----              ----  --------
  hello-world.info
                    /   web:8080 (10.244.0.100:8080)
Annotations:        <none>
Events:
  Type    Reason  Age                From                      Message
  ----    ------  ----               ----                      -------
  Normal  Sync    27m (x2 over 27m)  nginx-ingress-controller  Scheduled for sync